package me.zhengjie.modules.workorder.service.impl;

import me.zhengjie.exception.BadRequestException;
import me.zhengjie.modules.serviceprovider.domain.TServiceproviderPerson;
import me.zhengjie.modules.serviceprovider.repository.TServiceproviderPersonRepository;
import me.zhengjie.modules.system.common.EnumWorkorderStatus;
import me.zhengjie.modules.workorder.domain.TWorkOrder;
import me.zhengjie.modules.workorder.domain.TWorkOrderLog;
import me.zhengjie.modules.workorder.repository.TWorkOrderRepository;
import me.zhengjie.utils.*;
import me.zhengjie.modules.workorder.repository.TWorkOrderLogRepository;
import me.zhengjie.modules.workorder.service.TWorkOrderLogService;
import me.zhengjie.modules.workorder.service.dto.TWorkOrderLogDTO;
import me.zhengjie.modules.workorder.service.dto.TWorkOrderLogQueryCriteria;
import me.zhengjie.modules.workorder.service.mapper.TWorkOrderLogMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.sql.Timestamp;
import java.util.Date;
import java.util.Optional;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import springfox.documentation.spi.service.contexts.SecurityContext;

/**
* @author zcw
* @date 2019-11-03
*/
@Service
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class TWorkOrderLogServiceImpl implements TWorkOrderLogService {

    @Autowired
    private TWorkOrderLogRepository tWorkOrderLogRepository;

    @Autowired
    private TWorkOrderLogMapper tWorkOrderLogMapper;

    @Autowired
    private TWorkOrderRepository tWorkOrderRepository;

    @Autowired
    private TServiceproviderPersonRepository tServiceproviderPersonRepository;

    @Override
    public Object queryAll(TWorkOrderLogQueryCriteria criteria, Pageable pageable){
        Page<TWorkOrderLog> page = tWorkOrderLogRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),pageable);
        return PageUtil.toPage(page.map(tWorkOrderLogMapper::toDto));
    }

    @Override
    public Object queryAll(TWorkOrderLogQueryCriteria criteria){
        return tWorkOrderLogMapper.toDto(tWorkOrderLogRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder)));
    }

    @Override
    public TWorkOrderLogDTO findById(Long id) {
        Optional<TWorkOrderLog> tWorkOrderLog = tWorkOrderLogRepository.findById(id);
        ValidationUtil.isNull(tWorkOrderLog,"TWorkOrderLog","id",id);
        return tWorkOrderLogMapper.toDto(tWorkOrderLog.get());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public TWorkOrderLogDTO create(TWorkOrderLog resources) {
        return tWorkOrderLogMapper.toDto(tWorkOrderLogRepository.save(resources));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(TWorkOrderLog resources) {
        Optional<TWorkOrderLog> optionalTWorkOrderLog = tWorkOrderLogRepository.findById(resources.getId());
        ValidationUtil.isNull( optionalTWorkOrderLog,"TWorkOrderLog","id",resources.getId());

        TWorkOrderLog tWorkOrderLog = optionalTWorkOrderLog.get();
        // 此处需自己修改
        resources.setId(tWorkOrderLog.getId());
        tWorkOrderLogRepository.save(resources);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(Long id) {
        tWorkOrderLogRepository.deleteById(id);
    }

    @Override
    public void process(TWorkOrderLog log) {
        Optional<TWorkOrder> optionalTWorkOrder = tWorkOrderRepository.findById(Long.valueOf(log.getOrderId()));
        ValidationUtil.isNull(optionalTWorkOrder,"TWorkOrder","id",log.getOrderId());
        TWorkOrder order = optionalTWorkOrder.get();

        TWorkOrderLog lognew = new TWorkOrderLog();
        lognew.setOrderId(order.getOrderCode());  //根据工单号来处理
        lognew.setCreateTime(new Timestamp(System.currentTimeMillis()));
        lognew.setOperator(SecurityUtils.getName());
        lognew.setCellphone(SecurityUtils.getUsername()); //用户名与手机号码一致

        if(log.getOrderStatus().intValue()== EnumWorkorderStatus.ACCEPTED.getValue()) { //接单操作
            if(order.getStatus().intValue() != EnumWorkorderStatus.DISPATCHED.getValue()) {//非派单状态,不能处理
                throw new BadRequestException("该订单状态不能接单!");
            }
            Optional<TServiceproviderPerson> personOptional = tServiceproviderPersonRepository.findById(SecurityUtils.getUserId());
            TServiceproviderPerson person = personOptional.get();
            if(person == null || (person != null && StringUtils.isEmpty(person.getMajor()))) {
                throw new BadRequestException("工程师不存在,或工程师对应的类型等级信息为空"); //TODO@@@@@@
            }
            order.setMajor(person.getMajor());
            order.setLevel(person.getLevel());
            order.setEngineer(SecurityUtils.getUserId());
            order.setEngineerName(SecurityUtils.getName());
            order.setStatus(EnumWorkorderStatus.ACCEPTED.getValue());//接单状态
            tWorkOrderRepository.save(order);


            lognew.setOrderStatus(order.getStatus());
            lognew.setOperator(SecurityUtils.getName());
            lognew.setContent(String.format("工程师%s接单",SecurityUtils.getName()));
            tWorkOrderLogRepository.save(lognew);
        }

        if(log.getOrderStatus().intValue()== EnumWorkorderStatus.DENY.getValue()) { //接单操作
            if(order.getStatus().intValue() != EnumWorkorderStatus.DISPATCHED.getValue()) {//非派单状态,不能处理
                throw new BadRequestException("该订单状态不能拒单!");
            }
            order.setStatus(EnumWorkorderStatus.DENY.getValue());//接单状态
            tWorkOrderRepository.save(order);


            lognew.setOrderStatus(order.getStatus());
            lognew.setContent(String.format("工程师%s拒单",SecurityUtils.getName()));
            lognew.setOperator(SecurityUtils.getName());
            tWorkOrderLogRepository.save(lognew);
        }

        if(log.getOrderStatus().intValue()==EnumWorkorderStatus.ARRIVED.getValue()){ //到场处理
            if(order.getStatus().intValue() != EnumWorkorderStatus.ACCEPTED.getValue()) { //非接单状态,则报错
                throw new BadRequestException("该订单状态不能设置为到场!");
            }
            order.setStatus(EnumWorkorderStatus.ARRIVED.getValue());//接单状态
            tWorkOrderRepository.save(order);


            lognew.setOrderStatus(order.getStatus());
            lognew.setContent(String.format("工程师%s到场",SecurityUtils.getName()));
            lognew.setOperator(SecurityUtils.getName());
            tWorkOrderLogRepository.save(lognew);
        }
        if(log.getOrderStatus().intValue()==EnumWorkorderStatus.PROCESSING.getValue()){ //回单
            if(order.getStatus().intValue() != EnumWorkorderStatus.ARRIVED.getValue()
                    && order.getStatus().intValue() != EnumWorkorderStatus.PROCESSING.getValue()) {
                throw new BadRequestException("该订单状态不能回单");
            }
            order.setStatus(EnumWorkorderStatus.PROCESSING.getValue());//回单
            tWorkOrderRepository.save(order);


            lognew.setOrderStatus(order.getStatus());
            lognew.setContent(log.getContent());
            lognew.setOperator(SecurityUtils.getName());
            tWorkOrderLogRepository.save(lognew);
        }

        if(log.getOrderStatus().intValue()==EnumWorkorderStatus.BACK.getValue()){ //退单
            if(order.getStatus().intValue() != EnumWorkorderStatus.ARRIVED.getValue()
                    && order.getStatus().intValue() != EnumWorkorderStatus.PROCESSING.getValue()) {
                throw new BadRequestException("该订单状态不能退单");
            }
            order.setStatus(EnumWorkorderStatus.BACK.getValue());//回单
            tWorkOrderRepository.save(order);


            lognew.setOrderStatus(order.getStatus());
            lognew.setContent(String.format("工程师%s退单",SecurityUtils.getName()));
            lognew.setOperator(SecurityUtils.getName());
            tWorkOrderLogRepository.save(lognew);
        }

        if(log.getOrderStatus().intValue()==EnumWorkorderStatus.FINISHED.getValue()){ //结单
            if(order.getStatus().intValue() != EnumWorkorderStatus.ARRIVED.getValue()
                    && order.getStatus().intValue() != EnumWorkorderStatus.PROCESSING.getValue()) {
                throw new BadRequestException("该订单状态不能结单");
            }
            order.setStatus(EnumWorkorderStatus.FINISHED.getValue());//回单
            order.setFinishTime(new Timestamp(System.currentTimeMillis()));
            tWorkOrderRepository.save(order);


            lognew.setOrderStatus(order.getStatus());
            lognew.setContent(log.getContent());
            lognew.setOperator(SecurityUtils.getName());
            tWorkOrderLogRepository.save(lognew);
        }

        if(log.getOrderStatus().intValue()==EnumWorkorderStatus.CREATED.getValue()){ //退单

            order.setStatus(EnumWorkorderStatus.CREATED.getValue());//创单
            tWorkOrderRepository.save(order);

            lognew.setOrderStatus(order.getStatus());
            lognew.setContent(log.getContent());
            lognew.setOperator(SecurityUtils.getName());
            tWorkOrderLogRepository.save(lognew);
        }
    }
}